<template>
  <div style="background-color: #ececec; padding: 20px">
    <a-row :gutter="16">
      <a-col :span="14">
        <a-card title="配置" :bordered="false">
          <template #extra>
            <a-select
                ref="select"
                v-model:value="value1"
                style="width: 120px"
            >
              <a-select-option value="MySQL">MySQL</a-select-option>
              <a-select-option value="SQLServer" disabled>SQLServer</a-select-option>
              <a-select-option value="Oracle" disabled>Oracle</a-select-option>
            </a-select>
          </template>
          <a-form
              :model="formState"
              name="horizontal_login"
              layout="inline"
              autocomplete="off"
              @submit="onFinish"
          >
            <a-form-item
                label="表名"
                name="tableName"
                :rules="[{ required: true, message: '请输入表名' }]"
            >
              <a-input v-model:value="formState.tableName">
              </a-input>
            </a-form-item>

            <a-form-item
                label="表注释"
                name="tableComment"
                :rules="[{ required: true, message: '请输入表注释' }]"
            >
              <a-input v-model:value="formState.tableComment">
              </a-input>
            </a-form-item>
            <a-form-item>
              <a-button type="primary" html-type="submit">生成代码</a-button>
            </a-form-item>
            <a-form-item>
              <a-button type="primary" @click="showModal"><template #icon><ArrowUpOutlined /></template>逆向解析</a-button>
              <a-modal v-model:visible="visible" width="800px" title="建表语句逆向解析" @ok="handleOk">
                <a-textarea placeholder="在这里输入您创建表的SQL语句吧......" rows="20" v-model:value="modalCreateSQL"/>
              </a-modal>
            </a-form-item>
            <a-form-item>
              <a-select v-model:value="commonTableValue" @change="commonTableChange" :disabled="false" show-search
                        placeholder="常用表">
                <a-select-option v-for="key in commontable.commonTableOptions.keys()" :key="key">{{ commontable.commonTableOptions.get(key) }}</a-select-option>
              </a-select>
            </a-form-item>
          </a-form>
          <div>
              <div :style="{color: 'red',margin:'5px 0px'}">*拖动可排序</div>
            <a-table :columns="columns" :dataSource="dataSource"
                     :rowKey="record => record.id" :pagination="false"
                     :customRow="customRow"
            >
              <template #bodyCell="{ column, text, record }">
                <template v-if="column.dataIndex === 'fieldName'">
                  <a-input v-model:value="record.fieldName" :disabled="false"/>
                </template>
                <template v-else-if="column.dataIndex === 'fieldType'">
                  <a-select v-model:value="record.fieldType" :disabled="false" show-search :style="{width:'100%'}"
                            placeholder="输入可搜索">
                    <a-select-option v-for="option in mySqlTypeToJavaType.keys()" :key="option">{{ option }}</a-select-option>
                  </a-select>
                </template>
                <template v-if="column.dataIndex === 'fieldDefult'">
                  <a-input v-model:value="record.fieldDefult" :disabled="false"/>
                </template>
                <template v-if="column.dataIndex === 'fieldComment'">
                  <a-input v-model:value="record.fieldComment" :disabled="false"/>
                </template>
                <template v-else-if="column.dataIndex === 'fieldLen'">
                  <a-input v-model:value="record.fieldLen" :disabled="false"/>
                </template>
                <template v-else-if="column.dataIndex === 'notEmpty'">
                  <a-checkbox v-model:checked="record.notEmpty"/>
                </template>
                <template v-else-if="column.dataIndex === 'isPrimaryKey'">
                  <a-checkbox v-model:checked="record.isPrimaryKey"/>
                </template>
                <template v-else-if="column.dataIndex === 'isAutoIncrement'">
                  <a-checkbox v-model:checked="record.isAutoIncrement"/>
                </template>
                <template v-else-if="column.dataIndex === 'operation'">
                  <a-typography-link @click="deleteRow(record.id)">
                    <CloseOutlined />
                  </a-typography-link>
                </template>
              </template>
            </a-table>
            <div :style="{width:'100%',textAlign:'center',marginTop:'10px'}">
            <a-button @click="addRow"><template #icon><PlusOutlined /></template>添加一行</a-button>
            <a-button @click="importDefaultColumn"><template #icon><ImportOutlined /></template>导入标准字段</a-button>
            <a-button @click="clearMySQLColumn"><template #icon><ClearOutlined /></template>重置</a-button>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :span="10">
        <a-card title="结果" :bordered="false">
          <a-tabs v-model:activeKey="activeKey" :destroyInactiveTabPane="false">
            <a-tab-pane key="1" tab="建表SQL" forceRender="true">
              <a-collapse v-model:activeKey="sqlCollapseActiveKey" expand-icon-position="left">
                <a-collapse-panel key="1" header="建表SQL">
                  <div id="editorContainer" style="height: 400px;"></div>
                  <template #extra><span @click="copyEditorSQL('createTableSql',$event)" ><copy-outlined/>复制代码</span></template>
                </a-collapse-panel>
              </a-collapse>
            </a-tab-pane>
            <a-tab-pane key="2" tab="Java代码" forceRender="true">
              <label>前缀字符:<a-tooltip title="输入后，生成的类型前缀将被替换掉，例如t_student，前缀为t_,生成后将去除t_,即只保留student" color="blue">
                <question-circle-outlined/>
              </a-tooltip> </label>
              <a-input v-model:value="formState.tablePrefix" placeholder="请输入前缀" :style="{width:'40%',marginBottom:'5px',marginRight:'5px'}"/>
<!--              <a-select v-model:value="daoTypeValue" @change="onFinish" :disabled="false" show-search :style="{width:'40%'}"-->
<!--                        placeholder="框架选择">-->
<!--                <a-select-option v-for="key in daoType.keys()" :key="key">{{ daoType.get(key) }}</a-select-option>-->
<!--              </a-select>-->
              <a-collapse v-model:activeKey="javaCollapseActiveKey" expand-icon-position="left">
                <a-collapse-panel key="1" header="实体类" forceRender="true">
                  <div id="editorJavaEntityContainer" style="height: 400px;"></div>
                  <template #extra><span @click="copyEditorSQL('createJavaEntity',$event)" ><copy-outlined/>复制代码</span></template>
                </a-collapse-panel>
                <a-collapse-panel key="2" header="基于Mybatis-plus的DAO" forceRender="true">
                  <div id="editorJavaDaoContainer" style="height: 400px;"></div>
                  <template #extra><span @click="copyEditorSQL('createJavaDao',$event)" ><copy-outlined/>复制代码</span></template>
                </a-collapse-panel>
                <a-collapse-panel key="3" header="基于Mybatis-plus的Service" forceRender="true">
                  <div id="editorJavaServiceContainer" style="height: 400px;"></div>
                  <template #extra><span @click="copyEditorSQL('createJavaService',$event)" ><copy-outlined/>复制代码</span></template>
                </a-collapse-panel>
                <a-collapse-panel key="4" header="基于Mybatis-plus的ServiceImpl" forceRender="true">
                  <div id="editorJavaServiceImplContainer" style="height: 400px;"></div>
                  <template #extra><span @click="copyEditorSQL('createJavaServiceImpl',$event)" ><copy-outlined/>复制代码</span></template>
                </a-collapse-panel>
<!--                <a-collapse-panel key="5" header="Controller" forceRender="true">-->
<!--                  <div id="editorJavaControllerContainer" style="height: 400px;"></div>-->
<!--                  <template #extra><span @click="copyEditorSQL('createJavaController',$event)" ><copy-outlined/>复制代码</span></template>-->
<!--                </a-collapse-panel>-->
              </a-collapse>
            </a-tab-pane>
          </a-tabs>
        </a-card>
      </a-col>
    </a-row>
  </div>
</template>

<script lang="ts" setup>
import { ref ,onMounted,toRaw} from 'vue';
import { PlusOutlined,CloseOutlined,CopyOutlined,ImportOutlined,ClearOutlined,QuestionCircleOutlined,ArrowUpOutlined } from '@ant-design/icons-vue';
import {editor} from 'monaco-editor';
import {generator_mysql_code,generator_reverse_analysis} from "_hooks/generator_mysql_code";
import {generator_java_entity_code} from "_hooks/generator_java_entity_code";
import {generator_java_dao_code} from "_hooks/generator_java_dao_code"
import {generator_java_service_code} from "_hooks/generator_java_service_code";
import {generator_java_serviceimpl_code} from "_hooks/generator_java_serviceimpl_code";
import {mySqlTypeToJavaType} from "_hooks/constants/Constants"
import {import_mysql_default_column} from "_hooks/import_mysql_default_column"
import {FormState,Item,editorType} from "_types/codegenerator"
import { message } from 'ant-design-vue';
import * as commontable from "_hooks/commonTable"
const value1 = "MySQL";
const activeKey = ref('1');
const sqlCollapseActiveKey = ref('1')
const javaCollapseActiveKey = ref('1')
const commonTableValue = ref()
const daoTypeValue = ref('mp')
const formState = ref<FormState>({
  tableName: '',
  tableComment: '',
  tablePrefix:''
});
//逆向解析
// 弹出框显示
const visible = ref<boolean>(false);
//用于逆向解析的建表语句
const modalCreateSQL = ref<string>("CREATE TABLE `t_article` (\n" +
    "  `id` bigint NOT NULL AUTO_INCREMENT,\n" +
    "  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,\n" +
    "  `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,\n" +
    "  `pid` bigint DEFAULT NULL,\n" +
    "  `sort` int DEFAULT NULL,\n" +
    "  `last_modified` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,\n" +
    "  PRIMARY KEY (`id`) USING BTREE\n" +
    ") ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;");
const showModal = () => {
  visible.value = true;
};
const handleOk = (e: MouseEvent) => {
  visible.value = false;
  // 提取字段信息
  const {table_name,table_annotation,field_array} =generator_reverse_analysis(modalCreateSQL.value)
  //解析后的字段，放入对应位置
  formState.value.tableName = table_name;
  formState.value.tableComment = table_annotation;
  dataSource.value = field_array;
};


//建表的editor
const editorRef = ref<editor.IStandaloneCodeEditor | undefined>();
//javaEntity
const editorJavaEntityRef = ref<editor.IStandaloneCodeEditor | undefined>();
//javaDao
const editorJavaDaoRef = ref<editor.IStandaloneCodeEditor | undefined>();
//javaService
const editorJavaServiceRef = ref<editor.IStandaloneCodeEditor | undefined>();
//javaServiceImpl
const editorJavaServiceImplRef = ref<editor.IStandaloneCodeEditor | undefined>();
//javaController
const editorJavaControllerRef = ref<editor.IStandaloneCodeEditor | undefined>();



//
const editorTypeMap = ref<Map<string,editor.IStandaloneCodeEditor>>();

onMounted(() => {
  const editors = editor.create(document.getElementById('editorContainer') as HTMLElement, {
    value: "",
    language: "sql",
    // 代码略缩图
    minimap: {
      enabled: false
    },
    automaticLayout: true,
    theme: 'vs-dark'
  });
  editorRef.value = editors;
  const editorJavaEntity = editor.create(document.getElementById('editorJavaEntityContainer') as HTMLElement, {
    value: "",
    language: "java",
    // 代码略缩图
    minimap: {
      enabled: false
    },
    automaticLayout: true,
    theme: 'vs-dark'
  });
  editorJavaEntityRef.value = editorJavaEntity;
  const editorJavaDao = editor.create(document.getElementById('editorJavaDaoContainer') as HTMLElement, {
    value: "",
    language: "java",
    // 代码略缩图
    minimap: {
      enabled: false
    },
    automaticLayout: true,
    theme: 'vs-dark'
  });
  editorJavaDaoRef.value = editorJavaDao;
  const editorJavaService = editor.create(document.getElementById('editorJavaServiceContainer') as HTMLElement, {
    value: "",
    language: "java",
    // 代码略缩图
    minimap: {
      enabled: false
    },
    automaticLayout: true,
    theme: 'vs-dark'
  });
  editorJavaServiceRef.value = editorJavaService;
  const editorJavaServiceImpl = editor.create(document.getElementById('editorJavaServiceImplContainer') as HTMLElement, {
    value: "",
    language: "java",
    // 代码略缩图
    minimap: {
      enabled: false
    },
    automaticLayout: true,
    theme: 'vs-dark'
  });
  editorJavaServiceImplRef.value = editorJavaServiceImpl;
  // const editorJavaController = editor.create(document.getElementById('editorJavaControllerContainer') as HTMLElement, {
  //   value: "",
  //   language: "java",
  //   // 代码略缩图
  //   minimap: {
  //     enabled: false
  //   },
  //   automaticLayout: true,
  //   theme: 'vs-dark'
  // });
  // editorJavaControllerRef.value = editorJavaController;


  //编辑器对应的内容类型
  editorTypeMap.value =new Map ([
    ["createTableSql",toRaw(editorRef.value!)],
    ["createJavaEntity",toRaw(editorJavaEntityRef.value!)],
    ["createJavaDao",toRaw(editorJavaDaoRef.value!)],
    ["createJavaService",toRaw(editorJavaServiceRef.value!)],
    ["createJavaServiceImpl",toRaw(editorJavaServiceImplRef.value!)],
    // ["createJavaController",toRaw(editorJavaControllerRef.value!)]
  ])
});

let dataSource= ref<Item[]>([

]);

//常用表选择
const commonTableChange=()=>{
  commontable.commonTableChange(dataSource,formState,commonTableValue.value)
}
//生成代码
const onFinish = () => {
  //建表语句
 let content = generator_mysql_code(formState.value,dataSource.value)
  toRaw(editorRef.value!).setValue(content)
  //JavaEntity语句
  let contentJavaEntity = generator_java_entity_code(formState.value,dataSource.value,daoTypeValue.value)
  toRaw(editorJavaEntityRef.value!).setValue(contentJavaEntity)
  //Java-Mybatis-Plus DAO语句
  let contentJavaMPDAO = generator_java_dao_code(formState.value,dataSource.value,daoTypeValue.value)
  toRaw(editorJavaDaoRef.value!).setValue(contentJavaMPDAO)
  //Java-Mybatis-Plus Service语句
  let contentJavaMPService = generator_java_service_code(formState.value,dataSource.value,daoTypeValue.value)
  toRaw(editorJavaServiceRef.value!).setValue(contentJavaMPService)
  //Java-Mybatis-Plus Service-Impl语句
  let contentJavaMPServiceImpl = generator_java_serviceimpl_code(formState.value,dataSource.value,daoTypeValue.value)
  toRaw(editorJavaServiceImplRef.value!).setValue(contentJavaMPServiceImpl)
}

//拖动排序
let sourceObj:Item;
let targetObj:Item;
const customRow = (record:Item, index:number)=>{
  return {
    style: {
      cursor: "move",
    },
    // 鼠标移入
    onMouseenter: (event:any) => {
      // 兼容IE
      var ev = event || window.event;
      ev.target.draggable = true;
    },
    // 开始拖拽
    onDragstart: (event:any) => {
      // 兼容IE
      var ev = event || window.event;
      // 阻止冒泡
      ev.stopPropagation();
      // 得到源目标数据
      sourceObj = record;
    },
    // 拖动元素经过的元素
    onDragover: (event:any) => {
      // 兼容 IE
      var ev = event || window.event;
      // 阻止默认行为
      ev.preventDefault();
    },
    // 鼠标松开
    onDrop: (event:any) => {
      // 兼容IE
      var ev = event || window.event;
      // 阻止冒泡
      ev.stopPropagation();
      // 得到目标数据
      targetObj = record;
      console.log(sourceObj,targetObj);
      let sourceIndex =  dataSource.value.findIndex((item) => item.id === sourceObj.id);
      let targetIndex =  dataSource.value.findIndex((item) => item.id === targetObj.id);
      debugger
      if(sourceIndex>targetIndex){
        dataSource.value.splice(targetIndex,0,dataSource.value[sourceIndex]);
        dataSource.value.splice(sourceIndex+1,1)
      }else{
        dataSource.value.splice(targetIndex+1,0,dataSource.value[sourceIndex]);
        dataSource.value.splice(sourceIndex,1)
      }
    },
  };
}

//复制代码
const copyEditorSQL = (type:string,event: MouseEvent)=>{
  event.stopPropagation();
  let editor =editorTypeMap.value!.get(type)
  let cont = toRaw(editor!).getValue()
  navigator.clipboard.writeText(cont);
  message.success("已复制到剪切板")
}

//删除行
const deleteRow = (id:string) =>{
  dataSource.value = dataSource.value.filter((item) => item.id !== id);
}

//添加行
const addRow = () => {
  const items:Item = {
    id: Date.now().toString(),
    fieldName: "name",
    fieldType: "varchar",
    fieldLen: "256",
    fieldDefult:"",
    fieldComment:"名称",
    notEmpty:false,
    isPrimaryKey:false,
    isAutoIncrement:false,
    editable: true
  }
  dataSource.value.push(items)
};

//导入标准字段
const importDefaultColumn = ()=>{
  dataSource.value=dataSource.value.concat(import_mysql_default_column());
}

//重置
const clearMySQLColumn=()=>{
  formState.value ={
    tableName: '',
    tableComment: '',
    tablePrefix:''
  };
  dataSource.value=[];
}





//列明
const columns = ref([
  {
    title: '名称',
    dataIndex: 'fieldName',
    width: '15%',
  },
  {
    title: '类型',
    dataIndex: 'fieldType',
    width: '15%',
  },{
    title:'长度',
    dataIndex:'fieldLen',
    width: '11%',
  },{
    title:'默认值',
    dataIndex:'fieldDefult',
    width: '15%',
  },{
    title:'注释',
    dataIndex:'fieldComment',
    width: '15%',
  },{
    title:'非空',
    dataIndex:'notEmpty',
    width: '8%',
  },{
    title:'主键',
    dataIndex:'isPrimaryKey',
    width: '8%',
  },{
    title:'自增',
    dataIndex:'isAutoIncrement',
    width: '8%',
  },{
    title: '操作',
    dataIndex: 'operation',
    width: '5%'
  },
]);
</script>

<style scoped>

</style>
